﻿/*-----------------------------------------------
// File: BattleRoundCtrl.cs
// Description: 小回合逻辑控制器
// Author: Shaobing	492057342@qq.com
-----------------------------------------------*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace Battle.View
{
    public class BattleRoundCtrl : Fsm.FsmControllerBase<BattleRoundState>
    {
        public BattleRunningState runningState;
        public BattleViewCtrl viewCtrl {
            get { return runningState.viewCtrl; }
        }
        public BattleRoundCtrl(BattleRunningState runningState) {
            this.runningState = runningState;
            InitState();
        }
        public override void InitState()
        {
            allStates = new Dictionary<BattleRoundState, Fsm.FsmStateBase<BattleRoundState>>();
            allStates[BattleRoundState.ShowCampRunState] = new ShowCampRunState(BattleRoundState.ShowCampRunState, this);
            allStates[BattleRoundState.RoundEnterState] = new RoundEnterState(BattleRoundState.RoundEnterState, this);
            allStates[BattleRoundState.RoundWaitState] = new RoundWaitState(BattleRoundState.RoundWaitState, this);
            allStates[BattleRoundState.FormationTransferState] = new FormationTransferState(BattleRoundState.FormationTransferState, this);
            allStates[BattleRoundState.AttackingState] = new AttackState(BattleRoundState.AttackingState, this);
            allStates[BattleRoundState.UltimateBeforeState] = new UltimateBeforeState(BattleRoundState.UltimateBeforeState, this);
            allStates[BattleRoundState.UltimateState] = new UltimateState(BattleRoundState.UltimateState, this);
            allStates[BattleRoundState.UltimateEndState] = new UltimateEndState(BattleRoundState.UltimateEndState, this);
            allStates[BattleRoundState.RoundLeaveState] = new RoundLeaveState(BattleRoundState.RoundLeaveState, this);
        }

        public BattleCamp currentCamp {
            get { return BattleViewCtrl.GetInstance().curRunningCamp; }
            set { BattleViewCtrl.GetInstance().curRunningCamp = value; }
        }

        public void RoundLeave() {
            viewCtrl.AskRoundOver();
        }


        #region Ultimate Info
        /// <summary>
        /// 释放大招的BattleCharacter
        /// </summary>
        BattleCharacter sourceBC;
        /// <summary>
        /// 大招过程中被影响的与sourceBC相同阵营的BattleCharacter
        /// </summary>
        List<BattleCharacter> friendBCs = new List<BattleCharacter>();
        /// <summary>
        /// 大招过程中被影响的与sourceBC相对阵营的BattleCharacter
        /// </summary>
        List<BattleCharacter> targetBCs = new List<BattleCharacter>();
        /// <summary>
        /// 与大招过程无关的BattleCharacter
        /// </summary>
        List<BattleCharacter> otherBCs = new List<BattleCharacter>();

        public BattleCharacter GetSource() { return sourceBC; }
        public List<BattleCharacter> GetFriends() { return friendBCs; }
        public List<BattleCharacter> GetTargets() { return targetBCs; }
        public List<BattleCharacter> GetOthers() { return otherBCs; }

        public void InitBCs(UltimateBehaviourPackage package) {
            sourceBC = viewCtrl.GetBattleCharacter(package.actorUid);
            friendBCs = new List<BattleCharacter>();
            targetBCs = new List<BattleCharacter>();
            otherBCs = new List<BattleCharacter>();
            foreach (var uid in package.targetUids) {
                if (uid == sourceBC.uniqueId)
                    continue;
                var bc = viewCtrl.GetBattleCharacter(uid);
                if (bc != null && bc.camp == sourceBC.camp)
                {
                    if (!friendBCs.Contains(bc)) { friendBCs.Add(bc); }
                }
                else if (bc != null && bc.camp == BattleViewCtrl.GetOppoCamp(sourceBC.camp)) {
                    if (!targetBCs.Contains(bc)) { targetBCs.Add(bc); }
                }
            }
            foreach (var uid in BattleViewCtrl.GetInstance().GetActorUids(BattleCamp.Attacker)) {
                if (uid != package.actorUid && !package.targetUids.Contains(uid)) {
                    var bc = viewCtrl.GetBattleCharacter(uid);
                    otherBCs.Add(bc);
                }
            }
            foreach (var uid in BattleViewCtrl.GetInstance().GetActorUids(BattleCamp.Defender))
            {
                if (uid != package.actorUid && !package.targetUids.Contains(uid))
                {
                    var bc = viewCtrl.GetBattleCharacter(uid);
                    otherBCs.Add(bc);
                }
            }
        }


        List<OnceAttackPackageBase> ultimateCachePackages = new List<OnceAttackPackageBase>();
        Dictionary<string, double> ultimateHpCache = new Dictionary<string, double>();
        public void ClearUltimateCahce() {
            ultimateCachePackages = new List<OnceAttackPackageBase>();
            ultimateHpCache = new Dictionary<string, double>();
        }
        public void AddUltimateCache(OnceAttackPackageBase p) {
            ultimateCachePackages.Add(p);
            foreach (var hpExport in p.hpExports) {
                if (!ultimateHpCache.ContainsKey(hpExport.targetUid)) {
                    var bc = BattleViewCtrl.GetInstance().GetBattleCharacter(hpExport.targetUid);
                    ultimateHpCache.Add(hpExport.targetUid, bc.hp);
                }
            }
        }

        public List<OnceAttackPackageBase> GetUltimateCachePackages() { return ultimateCachePackages; }
        public Dictionary<string, double> GetUltimateHpCache() { return ultimateHpCache; }

        List<BCStateCache> ultimateStateCaches = new List<BCStateCache>();

        public void SetStateCaches() {
            ultimateStateCaches = new List<BCStateCache>();
            foreach (var friend in friendBCs) {
                var stateCache = BCStateCacheFactory.GetBCStateCache(friend);
                if (stateCache != null)
                    ultimateStateCaches.Add(stateCache);
            }
            foreach (var target in targetBCs) {
                var stateCache = BCStateCacheFactory.GetBCStateCache(target);
                if (stateCache != null)
                    ultimateStateCaches.Add(stateCache); 
            }
            foreach (var other in otherBCs)
            {
                var stateCache = BCStateCacheFactory.GetBCStateCache(other);
                if (stateCache != null)
                    ultimateStateCaches.Add(stateCache);
            }
        }
        public List<BCStateCache> GetStateCaches() { return ultimateStateCaches; }

        #endregion

    }
}
